Add an option to suggest improvements to paragraphs#1666
Conversation
📝 WalkthroughWalkthroughAdds end-to-end AI paragraph suggestion support: frontend Gutenberg toolbar and abilities, client backend call, paragraph HTML sanitization, server endpoint and Rust LLM integration, shared request/response types and guards, DB migration/seed, tests, and i18n strings across multiple locales. Changes
Sequence DiagramsequenceDiagram
actor User
participant Gutenberg as Gutenberg Editor
participant Toolbar as Paragraph AI Toolbar HOC
participant Registry as AI Abilities Registry
participant CMSClient as CMS Backend Client
participant Server as Headless-LMS Server
participant Chatbot as Chatbot Service
participant LLM as Language Model
User->>Gutenberg: edit paragraph / trigger AI action
Gutenberg->>Toolbar: open AI toolbar
Toolbar->>Registry: executeAbility(name, { text, meta })
Registry->>CMSClient: requestParagraphSuggestions(payload)
CMSClient->>Server: POST /api/v0/cms/ai-suggestions/paragraph
Server->>Server: auth, validate, fetch LLM config
Server->>Chatbot: generate_paragraph_suggestions(input)
Chatbot->>LLM: send JSON-schema guided request
LLM-->>Chatbot: return structured suggestions
Chatbot-->>Server: suggestions list
Server-->>CMSClient: ParagraphSuggestionResponse
CMSClient-->>Registry: ability result ({text, suggestions})
Registry-->>Toolbar: deliver suggestions
Toolbar->>User: show suggestion dialog (diff preview)
User->>Toolbar: confirm selection
Toolbar->>Gutenberg: update block content
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (7)
services/cms/src/services/backend/ai-suggestions.ts (1)
10-15: Add a brief doc comment for this exported API helper.Line 10 introduces a public function without a minimal intent/contract description.
♻️ Proposed change
+/** + * Requests AI-generated paragraph suggestions for a single paragraph action. + */ export async function requestParagraphSuggestions( payload: ParagraphSuggestionRequest, ): Promise<ParagraphSuggestionResponse> { const response = await cmsClient.post("/ai-suggestions/paragraph", payload) return validateResponse(response, isParagraphSuggestionResponse) }As per coding guidelines, "Require consistent, minimal function documentation... Public interfaces should have clearer and more comprehensive documentation."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@services/cms/src/services/backend/ai-suggestions.ts` around lines 10 - 15, Add a minimal doc comment above the exported function requestParagraphSuggestions describing its purpose, expected input and output contract: state that it sends a ParagraphSuggestionRequest to the "/ai-suggestions/paragraph" endpoint, returns a validated ParagraphSuggestionResponse (via validateResponse and isParagraphSuggestionResponse), and note any errors it may throw (e.g., network/validation errors). Keep the comment concise (one to three lines) and place it immediately above the requestParagraphSuggestions declaration.services/cms/src/utils/Gutenberg/ai/registry.ts (1)
3-3:categoriesregistry appears unused.The
categoriesMap andregisterAbilityCategoryfunction are defined butabilities.tsdoesn't register any categories. If this is scaffolding for future use, consider adding a brief comment to clarify intent, or remove if not needed.Also applies to: 6-9
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@services/cms/src/utils/Gutenberg/ai/registry.ts` at line 3, The categories Map (categories) and registerAbilityCategory function are defined but never used by abilities.ts; either remove the unused registry or document it as intentional scaffolding: if keeping, add a concise comment above const categories and export/register code noting it's reserved for future ability grouping and reference registerAbilityCategory and AbilityCategory so maintainers know why it's present; if removing, delete the categories declaration and registerAbilityCategory to avoid dead code and update any related exports in the module.services/headless-lms/chatbot/src/cms_ai_suggestion.rs (1)
17-17: Unused import.
BackendErroris imported but not used in this file.Suggested fix
-use headless_lms_utils::{ApplicationConfiguration, prelude::BackendError}; +use headless_lms_utils::ApplicationConfiguration;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@services/headless-lms/chatbot/src/cms_ai_suggestion.rs` at line 17, The import BackendError in the use statement (headless_lms_utils::{ApplicationConfiguration, prelude::BackendError}) is unused; remove BackendError from that use declaration or, if you intended to handle errors here, reference BackendError where appropriate (e.g., in function signatures or error handling in functions like suggest_from_cms_ai). Update the use line to only import ApplicationConfiguration or add the necessary BackendError usage to avoid the unused-import lint.services/cms/src/utils/Gutenberg/ai/abilities.ts (1)
128-132: Preferfor...ofoverforEachwhen not using return values.Static analysis flagged that
forEachcallbacks shouldn't return values (even implicitly). Usingfor...ofis cleaner here.Suggested fix
export function registerEditorAiAbilities(): void { registerAbility(fixSpellingAbility) - allPlaceholderAbilities.forEach((ability) => registerAbility(ability)) + for (const ability of allPlaceholderAbilities) { + registerAbility(ability) + } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@services/cms/src/utils/Gutenberg/ai/abilities.ts` around lines 128 - 132, The function registerEditorAiAbilities uses allPlaceholderAbilities.forEach(...) which static analysis flags; replace the forEach call with an explicit for...of loop to iterate over allPlaceholderAbilities and call registerAbility(ability) for each item (i.e., in registerEditorAiAbilities iterate: for (const ability of allPlaceholderAbilities) { registerAbility(ability) }) to avoid the forEach callback return-value issue and make intent clearer.services/headless-lms/server/src/controllers/cms/ai_suggestions.rs (1)
8-12:setting_typeis currently a no-op in the request contract.
ParagraphSuggestionMeta.setting_typeis accepted, but not forwarded intoCmsParagraphSuggestionInput(onlytoneandlanguageare passed). Either wire it through end-to-end or remove it for now to avoid a misleading API field.Also applies to: 81-86
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@services/headless-lms/server/src/controllers/cms/ai_suggestions.rs` around lines 8 - 12, ParagraphSuggestionMeta currently exposes setting_type but the controller does not forward it into CmsParagraphSuggestionInput (only tone and language are mapped); either propagate setting_type through the mapping and into CmsParagraphSuggestionInput and any downstream types/handlers that consume it (ensure field names and types align), or remove setting_type from ParagraphSuggestionMeta to avoid a no-op API field; update any serializers/deserializers and unit tests that reference ParagraphSuggestionMeta or CmsParagraphSuggestionInput to reflect the chosen change.services/cms/src/utils/Gutenberg/withParagraphAiToolbarAction.tsx (2)
145-147: Replace hardcoded color literals with theme tokens.This component currently mixes hardcoded colors/fallbacks (
#ddd,white,rgba(...)). Please switch these to shared theme values for consistency.As per coding guidelines: If a component uses colors, use colors from the theme if possible.
Also applies to: 304-307, 319-319
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@services/cms/src/utils/Gutenberg/withParagraphAiToolbarAction.tsx` around lines 145 - 147, The component withParagraphAiToolbarAction is using hardcoded color literals (e.g. "#ddd", "white", "rgba(...)") in its styled rules (see uses withSubmenu/hasSubmenu for border-right and other styles around the toolbar button, submenu and tooltip); replace those literals with the shared theme tokens or CSS variables (e.g. theme colors or existing --wp-admin-* vars) by referencing the theme object or CSS vars used elsewhere in the codebase, update the styles in the styled wrapper and any button/submenu/tooltip style blocks (the rules around hasSubmenu, the toolbar button styles, and submenu/tooltip blocks) to use the appropriate theme tokens for border, background and text/overlay colors, and ensure fallbacks use theme tokens rather than raw hex/rgba values.
35-37: Define a narrow interface for the block props instead ofany.The component accesses
props.name,props.attributes.content, andprops.setAttributes. A typed interface would catch contract issues here without overhead, e.g.:interface ParagraphBlockProps { name: string attributes: { content?: string } setAttributes: (attrs: Record<string, any>) => void // ... other BlockEdit props for spreadingNote: WordPress's
createHigherOrderComponentdoesn't export a standard BlockEdit props type, so you'd need to define this locally or derive it from block registration.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@services/cms/src/utils/Gutenberg/withParagraphAiToolbarAction.tsx` around lines 35 - 37, Replace the overly broad any on ParagraphWithAiToolbar props with a narrow local interface (e.g., ParagraphBlockProps) that includes at least name: string, attributes: { content?: string }, and setAttributes: (attrs: Record<string, any>) => void; update the component signature to use that interface and keep the rest of the incoming props via a spread type or index signature to preserve other BlockEdit fields so usages of props.name, props.attributes.content, and props.setAttributes are type-checked.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@services/headless-lms/server/src/controllers/cms/ai_suggestions.rs`:
- Around line 51-93: The DB connection acquired into conn is held across the
await to generate_paragraph_suggestions, starving the pool under load; after
you've finished all DB work (authorize(...) and
application_task_default_language_models::get_for_task(...) and creating
generator_input), explicitly release conn (e.g. drop(conn) or limit its scope)
before calling
headless_lms_chatbot::cms_ai_suggestion::generate_paragraph_suggestions so the
pool entry is returned; if you need DB after the LLM call, re-acquire a
connection then.
In `@shared-module/packages/common/src/locales/en/cms.json`:
- Line 132: Remove the unused "fix-spelling" locale key from this JSON (and
other locale files where it appears) so keys follow the ai-* convention; keep
and use the existing "ai-improve-fix-spelling-grammar" key referenced by
services/cms/src/utils/Gutenberg/ai/menu.ts (menu.ts line ~70) and other code
paths, ensuring no code references "fix-spelling" remain before deleting.
---
Nitpick comments:
In `@services/cms/src/services/backend/ai-suggestions.ts`:
- Around line 10-15: Add a minimal doc comment above the exported function
requestParagraphSuggestions describing its purpose, expected input and output
contract: state that it sends a ParagraphSuggestionRequest to the
"/ai-suggestions/paragraph" endpoint, returns a validated
ParagraphSuggestionResponse (via validateResponse and
isParagraphSuggestionResponse), and note any errors it may throw (e.g.,
network/validation errors). Keep the comment concise (one to three lines) and
place it immediately above the requestParagraphSuggestions declaration.
In `@services/cms/src/utils/Gutenberg/ai/abilities.ts`:
- Around line 128-132: The function registerEditorAiAbilities uses
allPlaceholderAbilities.forEach(...) which static analysis flags; replace the
forEach call with an explicit for...of loop to iterate over
allPlaceholderAbilities and call registerAbility(ability) for each item (i.e.,
in registerEditorAiAbilities iterate: for (const ability of
allPlaceholderAbilities) { registerAbility(ability) }) to avoid the forEach
callback return-value issue and make intent clearer.
In `@services/cms/src/utils/Gutenberg/ai/registry.ts`:
- Line 3: The categories Map (categories) and registerAbilityCategory function
are defined but never used by abilities.ts; either remove the unused registry or
document it as intentional scaffolding: if keeping, add a concise comment above
const categories and export/register code noting it's reserved for future
ability grouping and reference registerAbilityCategory and AbilityCategory so
maintainers know why it's present; if removing, delete the categories
declaration and registerAbilityCategory to avoid dead code and update any
related exports in the module.
In `@services/cms/src/utils/Gutenberg/withParagraphAiToolbarAction.tsx`:
- Around line 145-147: The component withParagraphAiToolbarAction is using
hardcoded color literals (e.g. "#ddd", "white", "rgba(...)") in its styled rules
(see uses withSubmenu/hasSubmenu for border-right and other styles around the
toolbar button, submenu and tooltip); replace those literals with the shared
theme tokens or CSS variables (e.g. theme colors or existing --wp-admin-* vars)
by referencing the theme object or CSS vars used elsewhere in the codebase,
update the styles in the styled wrapper and any button/submenu/tooltip style
blocks (the rules around hasSubmenu, the toolbar button styles, and
submenu/tooltip blocks) to use the appropriate theme tokens for border,
background and text/overlay colors, and ensure fallbacks use theme tokens rather
than raw hex/rgba values.
- Around line 35-37: Replace the overly broad any on ParagraphWithAiToolbar
props with a narrow local interface (e.g., ParagraphBlockProps) that includes at
least name: string, attributes: { content?: string }, and setAttributes: (attrs:
Record<string, any>) => void; update the component signature to use that
interface and keep the rest of the incoming props via a spread type or index
signature to preserve other BlockEdit fields so usages of props.name,
props.attributes.content, and props.setAttributes are type-checked.
In `@services/headless-lms/chatbot/src/cms_ai_suggestion.rs`:
- Line 17: The import BackendError in the use statement
(headless_lms_utils::{ApplicationConfiguration, prelude::BackendError}) is
unused; remove BackendError from that use declaration or, if you intended to
handle errors here, reference BackendError where appropriate (e.g., in function
signatures or error handling in functions like suggest_from_cms_ai). Update the
use line to only import ApplicationConfiguration or add the necessary
BackendError usage to avoid the unused-import lint.
In `@services/headless-lms/server/src/controllers/cms/ai_suggestions.rs`:
- Around line 8-12: ParagraphSuggestionMeta currently exposes setting_type but
the controller does not forward it into CmsParagraphSuggestionInput (only tone
and language are mapped); either propagate setting_type through the mapping and
into CmsParagraphSuggestionInput and any downstream types/handlers that consume
it (ensure field names and types align), or remove setting_type from
ParagraphSuggestionMeta to avoid a no-op API field; update any
serializers/deserializers and unit tests that reference ParagraphSuggestionMeta
or CmsParagraphSuggestionInput to reflect the chosen change.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 57d7f1d7-022e-4d85-927d-bde5f1b1784e
⛔ Files ignored due to path filters (1)
services/cms/pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (24)
services/cms/package.jsonservices/cms/src/components/editors/GutenbergEditor.tsxservices/cms/src/services/backend/ai-suggestions.tsservices/cms/src/utils/Gutenberg/ai/abilities.tsservices/cms/src/utils/Gutenberg/ai/menu.tsservices/cms/src/utils/Gutenberg/ai/registry.tsservices/cms/src/utils/Gutenberg/ai/types.tsservices/cms/src/utils/Gutenberg/withParagraphAiToolbarAction.tsxservices/headless-lms/chatbot/src/cms_ai_suggestion.rsservices/headless-lms/chatbot/src/lib.rsservices/headless-lms/migrations/20260304120000_add_cms_paragraph_suggestion_task.down.sqlservices/headless-lms/migrations/20260304120000_add_cms_paragraph_suggestion_task.up.sqlservices/headless-lms/models/src/application_task_default_language_models.rsservices/headless-lms/server/src/controllers/cms/ai_suggestions.rsservices/headless-lms/server/src/controllers/cms/mod.rsservices/headless-lms/server/src/programs/seed/seed_application_task_llms.rsservices/headless-lms/server/src/ts_binding_generator.rsshared-module/packages/common/src/bindings.guard.tsshared-module/packages/common/src/bindings.tsshared-module/packages/common/src/locales/ar/cms.jsonshared-module/packages/common/src/locales/en/cms.jsonshared-module/packages/common/src/locales/fi/cms.jsonshared-module/packages/common/src/locales/sv/cms.jsonshared-module/packages/common/src/locales/uk/cms.json
# Conflicts: # services/cms/package.json # services/cms/pnpm-lock.yaml
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@services/cms/src/utils/Gutenberg/ai/abilities.ts`:
- Around line 14-17: The paragraph request currently always sends context: null,
preventing page-specific auth; update the
ParagraphAbilityInput/ParagraphAbilityInputMeta usage so the page context is
forwarded instead of null: add/ensure a context field on
ParagraphAbilityInputMeta (or use existing meta.context) and change the two
callback sites that set context: null to use input.meta?.context (or the new
meta.context) so the backend can perform page-specific authorization; also
ensure callers that construct ParagraphAbilityInput populate meta.context with
the current page context.
In `@services/cms/src/utils/Gutenberg/withParagraphAiToolbarAction.tsx`:
- Around line 65-76: The handler in withParagraphAiToolbarAction (using
props.attributes?.content and calling executeAbility) sends/returns raw HTML
which strips inline formatting; before calling executeAbility extract plain text
from props.attributes.content (e.g., via a stripHTML/text-extraction util) and
send that to executeAbility, then either (a) map the AI's plain-text rewrite
back onto the original rich-text content to preserve inline markup (apply the
plain-text range mapping to props.attributes.content) or (b) if mapping is not
possible, reject the action when inline markup is present and show a message.
Also update ParagraphAiSuggestionDialog’s diff/preview (the component that
renders the suggestion) to render the extracted plain text or a rendered HTML
preview instead of showing raw HTML so users see formatted output. Ensure
references: props.attributes.content, executeAbility,
withParagraphAiToolbarAction, and ParagraphAiSuggestionDialog.
In `@services/headless-lms/chatbot/src/cms_ai_suggestion.rs`:
- Around line 77-91: The context-window guard currently computes used_tokens
from SYSTEM_PROMPT + USER_PROMPT_PREFIX + text but omits the dynamically-built
system_instructions (which includes action and meta_* fields); update the
token-counting logic to compute used_tokens from the final prompt that will be
sent (e.g., the full system_instructions string plus USER_PROMPT_PREFIX and
text) so large action or meta_* values are included in the check, and apply the
same fix to the second occurrence referenced around the later block (the other
place that builds system_instructions at lines ~113-117).
In `@services/headless-lms/server/src/controllers/cms/ai_suggestions.rs`:
- Around line 24-29: The ParagraphSuggestionRequest.action is an unchecked
string and must be validated before being embedded into the LLM prompt; update
the boundary in the handler (where generate_paragraph_suggestions is called) to
map/validate action against a shared enum or allowlist (e.g., define a
ParagraphSuggestionAction enum) and reject any unknown value with an early error
response instead of passing it to generate_paragraph_suggestions; apply the same
validation for the other occurrence mentioned (lines ~80-87) so only allowed
actions reach the system prompt.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: e8e1f4bb-5d8d-4ba3-a7c4-6442da8a4740
📒 Files selected for processing (13)
services/cms/package.jsonservices/cms/src/components/editors/GutenbergEditor.tsxservices/cms/src/services/backend/ai-suggestions.tsservices/cms/src/utils/Gutenberg/ai/abilities.tsservices/cms/src/utils/Gutenberg/ai/registry.tsservices/cms/src/utils/Gutenberg/withParagraphAiToolbarAction.tsxservices/headless-lms/chatbot/src/cms_ai_suggestion.rsservices/headless-lms/server/src/controllers/cms/ai_suggestions.rsshared-module/packages/common/src/locales/ar/cms.jsonshared-module/packages/common/src/locales/en/cms.jsonshared-module/packages/common/src/locales/fi/cms.jsonshared-module/packages/common/src/locales/sv/cms.jsonshared-module/packages/common/src/locales/uk/cms.json
🚧 Files skipped from review as they are similar to previous changes (2)
- services/cms/src/components/editors/GutenbergEditor.tsx
- services/cms/package.json
services/cms/src/utils/Gutenberg/withParagraphAiToolbarAction.tsx
Outdated
Show resolved
Hide resolved
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
🧹 Nitpick comments (2)
services/cms/src/utils/Gutenberg/withParagraphAiToolbarAction.tsx (1)
422-427: Remove the empty object comment artifact.Line 423 contains an empty object
{}that appears to be a leftover artifact. This produces no output but adds noise.🧹 Proposed cleanup
> - {} <div dangerouslySetInnerHTML={{ __html: suggestionPreviewHtml || originalPreviewHtml }} />🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@services/cms/src/utils/Gutenberg/withParagraphAiToolbarAction.tsx` around lines 422 - 427, Remove the stray empty object JSX artifact `{}` inside the render block near the div that uses dangerouslySetInnerHTML (the element referencing suggestionPreviewHtml || originalPreviewHtml) in withParagraphAiToolbarAction.tsx; simply delete the `{}` so the JSX contains only the surrounding elements and the <div dangerouslySetInnerHTML={{ __html: suggestionPreviewHtml || originalPreviewHtml }} /> to eliminate the noise.services/headless-lms/chatbot/src/cms_ai_suggestion.rs (1)
70-77: Consider using theis_htmlflag.The
is_htmlfield is extracted but not used. If this is intentional (e.g., for future use or logging), consider adding a brief comment explaining why. Alternatively, if the LLM should handle HTML vs plain text differently, you could incorporate this into the prompt construction.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@services/headless-lms/chatbot/src/cms_ai_suggestion.rs` around lines 70 - 77, The destructured field is_html from CmsParagraphSuggestionInput is extracted but never used; either incorporate it into the prompt or explicitly document why it’s ignored. Update the code around the CmsParagraphSuggestionInput destructuring (and any prompt builder like the function that creates the LLM prompt for paragraph suggestions) to branch on is_html — e.g., adjust prompt text or mark content as HTML vs plain text so the LLM handles formatting correctly — or if omission is intentional, add a short inline comment next to the is_html binding explaining it’s intentionally unused for now (or add a TODO referencing future HTML handling).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@services/cms/src/utils/Gutenberg/withParagraphAiToolbarAction.tsx`:
- Around line 422-427: Remove the stray empty object JSX artifact `{}` inside
the render block near the div that uses dangerouslySetInnerHTML (the element
referencing suggestionPreviewHtml || originalPreviewHtml) in
withParagraphAiToolbarAction.tsx; simply delete the `{}` so the JSX contains
only the surrounding elements and the <div dangerouslySetInnerHTML={{ __html:
suggestionPreviewHtml || originalPreviewHtml }} /> to eliminate the noise.
In `@services/headless-lms/chatbot/src/cms_ai_suggestion.rs`:
- Around line 70-77: The destructured field is_html from
CmsParagraphSuggestionInput is extracted but never used; either incorporate it
into the prompt or explicitly document why it’s ignored. Update the code around
the CmsParagraphSuggestionInput destructuring (and any prompt builder like the
function that creates the LLM prompt for paragraph suggestions) to branch on
is_html — e.g., adjust prompt text or mark content as HTML vs plain text so the
LLM handles formatting correctly — or if omission is intentional, add a short
inline comment next to the is_html binding explaining it’s intentionally unused
for now (or add a TODO referencing future HTML handling).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: bd421381-f314-462a-adde-55baeebbf7ec
⛔ Files ignored due to path filters (1)
services/cms/pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (20)
services/cms/package.jsonservices/cms/src/utils/Gutenberg/ai/abilities.tsservices/cms/src/utils/Gutenberg/paragraphAiSource.tsservices/cms/src/utils/Gutenberg/paragraphHtmlSanitizer.tsservices/cms/src/utils/Gutenberg/withParagraphAiToolbarAction.tsxservices/cms/tests/utils/paragraphAiSource.test.tsservices/cms/tests/utils/paragraphHtmlSanitizer.test.tsservices/headless-lms/chatbot/src/cms_ai_suggestion.rsservices/headless-lms/models/src/user_chapter_locking_statuses.rsservices/headless-lms/server/src/controllers/cms/ai_suggestions.rsshared-module/packages/common/src/bindings.guard.tsshared-module/packages/common/src/bindings.tssystem-tests/src/tests/oauth/authorize/code-issuance.spec.tssystem-tests/src/tests/oauth/discovery.spec.tssystem-tests/src/tests/oauth/introspect.spec.tssystem-tests/src/tests/oauth/revocation.spec.tssystem-tests/src/tests/oauth/token/refresh.spec.tssystem-tests/src/tests/oauth/userinfo/bearer.spec.tssystem-tests/src/tests/oauth/userinfo/dpop.spec.tssystem-tests/src/tests/oauth/userinfo/scopes.spec.ts
✅ Files skipped from review due to trivial changes (3)
- system-tests/src/tests/oauth/userinfo/bearer.spec.ts
- system-tests/src/tests/oauth/discovery.spec.ts
- system-tests/src/tests/oauth/revocation.spec.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- shared-module/packages/common/src/bindings.guard.ts
- services/cms/src/utils/Gutenberg/ai/abilities.ts
- services/headless-lms/server/src/controllers/cms/ai_suggestions.rs
Summary by CodeRabbit
New Features
Content Safety
Localization
Tests